/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.vanvalt.payhui.modules.pay.web;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.thinkgem.jeesite.common.beanvalidator.BeanValidators;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.common.utils.excel.ExportExcel;
import com.thinkgem.jeesite.common.utils.excel.ImportExcel;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.SystemService;
import com.thinkgem.jeesite.modules.sys.utils.DictUtils;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import com.vanvalt.payhui.modules.pay.entity.Profit;
import com.vanvalt.payhui.modules.pay.entity.ProfitData;
import com.vanvalt.payhui.modules.pay.entity.UserPlatform;
import com.vanvalt.payhui.modules.pay.service.ProfitDataService;
import com.vanvalt.payhui.modules.pay.service.ProfitService;
import com.vanvalt.payhui.modules.pay.service.UserPlatformService;
import com.vanvalt.payhui.util.comm.Arith;
import com.vanvalt.payhui.util.comm.StringUtil;
import com.vanvalt.payhui.util.constat.Constant;

/**
 * 分润Controller
 * @author Xiaoyang
 * @version 2013-8-29
 */
@Controller
@RequestMapping(value = "${adminPath}/pay/profit")
public class ProfitController extends BaseController {

	@Autowired
	private ProfitDataService profitDataService;
	
	@Autowired
	private ProfitService profitService;
	
	@Autowired
	private SystemService systemService;
	
	@Autowired
	private UserPlatformService userPlatformService;
	
	@ModelAttribute
	public ProfitData get(@RequestParam(required=false) String id) {
		if (StringUtils.isNotBlank(id)){
			return profitDataService.get(id);
		} else {
			return new ProfitData();
		}
	}

	@RequestMapping(value = {"list", ""})
	public String list(ProfitData profitData, HttpServletRequest request, HttpServletResponse response, Model model) {
		Page<ProfitData> page = profitDataService.findPage(new Page<ProfitData>(request, response), profitData);
        model.addAttribute("page", page);
        
        List<String> years = this.getYearList();
        model.addAttribute("years", years);
        
        String currentYear = this.getCurrentYear(years);
        //model.addAttribute("currentYear", currentYear);
        
        List<String> months = this.getMonthList(currentYear);
        model.addAttribute("months", months);
        
        /*String currentMonth = this.getCurrentMonth(currentYear);
        model.addAttribute("currentMonth", currentMonth);*/
        
		return "modules/pay/profitList";
	}
	
	@ResponseBody
	@RequestMapping(value = {"listData"})
	public Page<ProfitData> listData(ProfitData profitData, HttpServletRequest request, HttpServletResponse response, Model model) {
		Page<ProfitData> page = profitDataService.findPage(new Page<ProfitData>(request, response), profitData);
		return page;
	}

	@RequestMapping(value = "form")
	public String form(ProfitData profitData, Model model) {
		
		model.addAttribute("profitData", profitData);
		return "modules/pay/profitForm";
	}

	@RequestMapping(value = "save")
	public String save(ProfitData profitData, HttpServletRequest request, Model model, RedirectAttributes redirectAttributes) {
		if(Global.isDemoMode()){
			addMessage(redirectAttributes, "演示模式，不允许操作！");
			return "redirect:" + adminPath + "/pay/profit/list?repage";
		}
		
		if (!beanValidator(model, profitData)){
			return form(profitData, model);
		}
		/*if (!"true".equals(checkLoginName(user.getOldLoginName(), user.getLoginName()))){
			addMessage(model, "保存用户'" + user.getLoginName() + "'失败，会员名已存在");
			return form(user, model);
		}*/
		
		/*String categoryId = profitData.getCategoryId();
		if(categoryId != null && !"".equals(categoryId)){
			String categoryName = DictUtils.getDictLabel(categoryId, Constant.PROFIT_CATEGORY, "");
			profitData.setCategoryName(categoryName);
		}*/
		profitDataService.save(profitData);
		
		addMessage(redirectAttributes, "保存用户'" + profitData.getUserName() + "'分润记录成功");
		return "redirect:" + adminPath + "/pay/profit/list?repage";
	}
	
	@RequestMapping(value = "delete")
	public String delete(ProfitData profitData, RedirectAttributes redirectAttributes) {
		if(Global.isDemoMode()){
			addMessage(redirectAttributes, "演示模式，不允许操作！");
			return "redirect:" + adminPath + "/pay/profit/list?repage";
		}
		
		profitDataService.delete(profitData);
		addMessage(redirectAttributes, "删除用户分润成功");
		
		return "redirect:" + adminPath + "/pay/profit/list?repage";
	}
	
	/**
	 * 导出用户分润数据
	 * @param profitData
	 * @param request
	 * @param response
	 * @param redirectAttributes
	 * @return
	 */
    @RequestMapping(value = "export", method=RequestMethod.POST)
    public String exportFile(ProfitData profitData, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
		try {
            String fileName = "用户数据"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
            Page<ProfitData> page = profitDataService.findPage(new Page<ProfitData>(request, response, -1), profitData);
    		new ExportExcel("用户数据", ProfitData.class).setDataList(page.getList()).write(response, fileName).dispose();
    		return null;
		} catch (Exception e) {
			addMessage(redirectAttributes, "导出用户分润记录失败！失败信息："+e.getMessage());
		}
		return "redirect:" + adminPath + "/pay/profit/list?repage";
    }

	/**
	 * 导入用户分润数据
	 * @param file
	 * @param redirectAttributes
	 * @return
	 */
    @RequestMapping(value = "import", method=RequestMethod.POST)
    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
		if(Global.isDemoMode()){
			addMessage(redirectAttributes, "演示模式，不允许操作！");
			return "redirect:" + adminPath + "/pay/profit/list?repage";
		}
		try {
			int successNum = 0;
			int failureNum = 0;
			StringBuilder failureMsg = new StringBuilder();
			// 数据文件，标题行（数据行+1），工作表编号
			ImportExcel ei = new ImportExcel(file, 1, 0);
			List<ProfitData> list = ei.getDataList(ProfitData.class);
			for (ProfitData profitData : list){
				try{
					/*if ("true".equals(checkUserName(profitData.getUserName()))){
						
					} else {
						failureMsg.append("<br/>会员名 "+profitData.getUserName()+" 不存在; ");
						failureNum++;
					}*/
					 // 系统存在该用户名
					BeanValidators.validateWithException(validator, profitData);
					
					String issueYear = profitData.getIssueYear();
					String issueMonth = profitData.getIssueMonth();
					// 平台代码
					String platformCode = profitData.getPlatformCode();
					// 平台会员代号
					String platformUserCode = profitData.getPlatformUserCode();
					
					String userId = null;
					String userName = null;
					
					boolean validate = true;
					logger.info("Data Validation Start:");
					if(issueYear != null && !"".equals(issueYear)){
						
						if(issueMonth != null && !"".equals(issueMonth)){
							issueMonth = StringUtil.monthFormat(issueMonth); //两位数字的月份（不足两位前面补0）
							
							if(platformCode != null && !"".equals(platformCode)){
								
								// 校验分润的平台类型
								String platformLabel = DictUtils.getDictLabel(platformCode, Constant.PROFIT_PLATFORM, "");
								if(platformLabel == null || "".equals(platformLabel)){
									failureMsg.append("<br/> 会员名"+profitData.getPlatformUserName()+" 平台不存在 ; ");
									failureNum++;
									validate = false;
								} else {
									profitData.setPlatformName(platformLabel);
									
									if(platformUserCode == null || "".equals(platformUserCode)){
										failureMsg.append("<br/> 会员名"+profitData.getPlatformUserName()+" 平台会员代号不能为空 ; ");
										failureNum++;
										validate = false;
									} else {
										
										UserPlatform userPlatformEntity = new UserPlatform();
										userPlatformEntity.setPlatformId(platformCode);
										userPlatformEntity.setPlatformUserCode(platformUserCode);
										List<UserPlatform> userPlatformList = userPlatformService.findList(userPlatformEntity);
										
										if(userPlatformList == null || userPlatformList.size() == 0){
											failureMsg.append("<br/> 会员名"+profitData.getPlatformUserName()+" 平台会员代号与平台代码未绑定 ; ");
											failureNum++;
											validate = false;
										} else {
											
											UserPlatform up = userPlatformList.get(0);
											userId = up.getUserId();
											userName = up.getUserName();
										}
									}
								}
							} else {
								failureMsg.append("<br/> 会员名"+profitData.getPlatformUserName()+" 平台代码不能为空 ; ");
								failureNum++;
								validate = false;
							}
						} else {
							failureMsg.append("<br/> 会员名"+profitData.getPlatformUserName()+" 月份不能为空 ; ");
							failureNum++;
							validate = false;
						}
					} else {
						failureMsg.append("<br/> 会员名"+profitData.getPlatformUserName()+" 年份不能为空 ; ");
						failureNum++;
						validate = false;
					}
					
					logger.info("Data Validation End:");
						
					if(!validate){ // 若数据校验不通过，则跳出本次循环
						continue;
					} else { // 数据校验通过
						
						//User user = systemService.getUserByLoginName(userName);
						
						if(userId != null){
							
							// 查询该用户在当前平台下当月是否存在分润记录
							ProfitData profitDataEntity = new ProfitData();
							profitDataEntity.setUserId(userId);
							profitDataEntity.setPlatformCode(platformCode);
							profitDataEntity.setUserName(userName);
							profitDataEntity.setIssueYear(issueYear);
							profitDataEntity.setIssueMonth(issueMonth);
							
							List<ProfitData> profitDataList = profitDataService.findList(profitDataEntity);
							
							Profit profitEntity = new Profit();
							profitEntity.setUserName(userName);
							profitEntity.setIssueYear(issueYear);
							profitEntity.setIssueMonth(issueMonth);
							// 根据用户名、YEAR、MONTH判断该用户当月是否存在分润记录
							List<Profit> profitList = profitService.findList(profitEntity);
							
							if(profitDataList == null || profitDataList.size() == 0){ // 若该用户在当前平台下当月不存在分润记录，则新增分润记录
								
								Profit profit = null;
								if(profitList != null && profitList.size() > 0){ // 该用户当月已存在分润记录汇总记录
									profit = profitList.get(0);
									String originalAmount = profit.getAmount();
									String increasedAmount = profitData.getAmount();
									double newAmount = Arith.add(Double.parseDouble(originalAmount), Double.parseDouble(increasedAmount));
									profit.setAmount(Double.toString(newAmount));
									
									profitService.save(profit);
								} else { // 该用户当月不存在分润汇总记录，则新增分润汇总记录
									profit = new Profit();
									profit.setUserId(userId);
									profit.setUserName(userName);
									profit.setAmount(profitData.getAmount());
									profit.setIssueYear(issueYear);
									profit.setIssueMonth(issueMonth);
									
									profitService.save(profit);
								}
								
								profitData.setProfitId(profit.getId());
								profitData.setUserId(userId);
								profitData.setUserName(userName);
								profitDataService.save(profitData);
								successNum++;
							} else { // 若该用户在当前平台下当月存在分润记录，则进行累加
								
								ProfitData oProfitData = profitDataList.get(0);
								String originalAmount = oProfitData.getAmount();
								double increaseAmount = Arith.sub(Double.parseDouble(profitData.getAmount()), Double.parseDouble(originalAmount));
								
								oProfitData.setAmount(profitData.getAmount());
								profitDataService.save(oProfitData);
								
								if(profitList != null && profitList.size() > 0){
									
									Profit profit = profitList.get(0);
									double newAmount = Arith.add(Double.parseDouble(profit.getAmount()), increaseAmount);
									profit.setAmount(Double.toString(newAmount));
									
									profitService.save(profit);
								}
							}
							
						}
					}
					
				
				} catch (ConstraintViolationException ex){
					failureMsg.append("<br/>会员名 "+profitData.getPlatformUserName()+" 导入失败：");
					List<String> messageList = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
					for (String message : messageList){
						failureMsg.append(message+"; ");
						failureNum++;
					}
				} catch (Exception ex) {
					failureMsg.append("<br/>会员名 "+profitData.getPlatformUserName()+" 导入失败："+ex.getMessage());
				}
			}
			if (failureNum>0){
				failureMsg.insert(0, "，失败 "+failureNum+" 条用户分润记录，导入信息如下：");
			}
			addMessage(redirectAttributes, "已成功导入 "+successNum+" 条用户分润记录"+failureMsg);
		} catch (Exception e) {
			addMessage(redirectAttributes, "导入用户分润记录失败！失败信息："+e.getMessage());
		}
		return "redirect:" + adminPath + "/pay/profit/list?repage";
    }
	
    
	/**
	 * 下载导入用户数据模板
	 * @param response
	 * @param redirectAttributes
	 * @return
	 */
    @RequestMapping(value = "import/template")
    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
		try {
            String fileName = "用户数据导入模板.xlsx";
    		List<User> list = Lists.newArrayList(); list.add(UserUtils.getUser());
    		new ExportExcel("用户数据", User.class, 2).setDataList(list).write(response, fileName).dispose();
    		return null;
		} catch (Exception e) {
			addMessage(redirectAttributes, "导入模板下载失败！失败信息："+e.getMessage());
		}
		return "redirect:" + adminPath + "/sys/user/list?repage";
    }
    
    /**
	 * 分润汇总列表
	 * @param profit
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "sum")
	public String profitSum(Profit profit, HttpServletRequest request, HttpServletResponse response, Model model) {
		Page<Profit> page = profitService.findPage(new Page<Profit>(request, response), profit);
        model.addAttribute("page", page);
        
        List<String> years = this.getProfitYearList();
        model.addAttribute("years", years);
        
        String currentYear = this.getCurrentYear(years);
        //model.addAttribute("currentYear", currentYear);
        
        List<String> months = this.getProfitMonthList(currentYear);
        model.addAttribute("months", months);
        
        return "modules/pay/profitSumList";
	}
    
    
    
    
    
	/**
	 * 验证会员名是否有效
	 * @param oldLoginName
	 * @param loginName
	 * @return
	 */
	@ResponseBody
	@RequiresPermissions("sys:user:edit")
	@RequestMapping(value = "checkLoginName")
	public String checkLoginName(String oldLoginName, String loginName) {
		if (loginName !=null && loginName.equals(oldLoginName)) {
			return "true";
		} else if (loginName !=null && systemService.getUserByLoginName(loginName) == null) {
			return "true";
		}
		return "false";
	}
	
	public String checkUserName(String loginName) {
		if (loginName !=null && systemService.getUserByLoginName(loginName) != null) {
			return "true";
		}
		return "false";
	}
	
	/**
	 * 获取年份列表
	 * @return
	 */
	private List<String> getYearList(){
		
		List<String> yearList = Lists.newArrayList();
		
		Map<String,Object> params = new HashMap<String,Object>();
        params.put("DEL_FLAG_NORMAL", Constant.DEL_FLAG_NORMAL);
        yearList = profitDataService.getYearList(params);
        
        return yearList;
	}
	
	private List<String> getProfitYearList(){
		
		List<String> yearList = Lists.newArrayList();
		
		Map<String,Object> params = new HashMap<String,Object>();
        params.put("DEL_FLAG_NORMAL", Constant.DEL_FLAG_NORMAL);
        yearList = profitService.getYearList(params);
        
        return yearList;
	}
	
	/**
	 * 获取月份列表
	 * @param year
	 * @return
	 */
	private List<String> getMonthList(String year){
		
		List<String> monthList = new ArrayList<String>();
		
		if(year != null && !"".equals(year)){
			Map<String,Object> params = Maps.newHashMap();
			params.put("DEL_FLAG_NORMAL", Constant.DEL_FLAG_NORMAL);
			params.put("issueYear", year);
			monthList = profitDataService.getMonthListByYear(params);
		}
		
		return monthList;
	}
	
	/**
	 * 获取月份列表
	 * @param year
	 * @return
	 */
	private List<String> getProfitMonthList(String year){
		
		List<String> monthList = new ArrayList<String>();
		
		if(year != null && !"".equals(year)){
			Map<String,Object> params = Maps.newHashMap();
			params.put("DEL_FLAG_NORMAL", Constant.DEL_FLAG_NORMAL);
			params.put("issueYear", year);
			monthList = profitService.getMonthListByYear(params);
		}
		
		return monthList;
	}
	
	/**
	 * 获取当前年份
	 * @param years
	 * @return
	 */
	private String getCurrentYear(List<String> years){
		
		String year = "";
		
		Calendar a = Calendar.getInstance();
		String currentYear = String.valueOf(a.get(Calendar.YEAR));
		
		if(years != null && years.size() > 0){
			
			for(String y:years){
				if(currentYear != null && currentYear.equals(y)){
					year = currentYear;
				}
			}
			
			if(year == null || "".equals(year)){
				int len = years.size();
				year = years.get(len-1);
			}
		}
		
		return year;
	}
	
	/**
	 * 获取当前年份
	 * @return
	 */
	private String getCurrentYear(){
		
		String year = "";
		
		Calendar a = Calendar.getInstance();
		String currentYear = String.valueOf(a.get(Calendar.YEAR));
		
		List<String> years = this.getYearList();
		
		if(years != null && years.size() > 0){
			
			for(String y:years){
				if(currentYear != null && currentYear.equals(y)){
					year = currentYear;
				}
			}
			
			if(year == null || "".equals(year)){
				int len = years.size();
				year = years.get(len-1);
			}
		}
		
		return year;
	}
	
	/**
	 * 获取当前月份
	 * @param months
	 * @return
	 */
	private String getCurrentMonth(List<String> months){
		
		String month = "";
		
		Date date = new Date();
		String currentMonth = String.format("%tm%n", date);
		
		if(months != null && months.size() > 0){
			
			if(months != null && months.size() > 0){
				
				for(String m:months){
					if(currentMonth != null && currentMonth.equals(m)){
						month = currentMonth;
					}
				}
			}
			
			if(month == null || "".equals(month)){
				int len = months.size();
				month = months.get(len-1);
			}
		}
		
		return month;
	}
	
	/**
	 * 获取当前月份
	 * @param year
	 * @return
	 */
	private String getCurrentMonth(String year){
		
		String month = "";
		
		Date date = new Date();
		String currentMonth = String.format("%tm%n", date);
		
		if(year != null && !"".equals(year)){
			
			List<String> months = this.getMonthList(year);
			if(months != null && months.size() > 0){
				
				for(String m:months){
					if(currentMonth != null && currentMonth.equals(m)){
						month = currentMonth;
					}
				}
			}
			
			if(month == null || "".equals(month)){
				int len = months.size();
				month = months.get(len-1);
			}
		}
		
		return month;
	}

}
